#include "../DWMRICore/Scalar.h"

#include <teem/ten.h>

#include <time.h>
#define _USE_MATH_DEFINES
#include <math.h>

char *pSrcPathname = NULL;
char *pDstPathname = NULL;
int npass = 1;

CScalar *pData = NULL;

void PrintUsage()
{
	printf("Usage: Dilate -src src_file -dst dst_file [-pass npass]\n");
}

int ParseArguments(const int argc, char *argv[])
{
	for (int i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "-src") == 0) {
			pSrcPathname = argv[++i];
		} else if (strcmp(argv[i], "-dst") == 0) {
			pDstPathname = argv[++i];
		} else if (strcmp(argv[i], "-pass") == 0) {
			npass = atoi(argv[++i]);
		} else {
			return -1;
		}
	}

	if (pSrcPathname == NULL || pDstPathname == NULL)
		return -2;

	return 0;
}

void Dilate()
{
	int w = pData->GetWidth();
	int h = pData->GetHeight();
	int d = pData->GetDepth();

	for (int z = 1; z < d-1; ++z) {
		for (int y = 1; y < h-1; ++y) {
			for (int x = 1; x < w-1; ++x) {
				if (pData->GetScalarFast(x, y, z) < 0.5f && pData->GetScalarFast(x, y, z) > -0.5f) {
					int min_x = (x - 1);
					int max_x = (x + 1);
					int min_y = (y - 1);
					int max_y = (y + 1);
					int min_z = (z - 1);
					int max_z = (z + 1);

					for (int cz = min_z; cz <= max_z; ++cz) {
						for (int cy = min_y; cy <= max_y; ++cy) {
							for (int cx = min_x; cx <= max_x; ++cx) {
								if (pData->GetScalarFast(cx, cy, cz) > 0.5f) {
									pData->SetScalar(cx, cy, cz, -1.0f);
								}
							}
						}
					}
				}
			}
			//printf("y = %d\n", y);
		}
		//printf("z = %d\n", z);
	}

	for (int z = 0; z < d; ++z) {
		for (int y = 0; y < h; ++y) {
			for (int x = 0; x < w; ++x) {
				if (pData->GetScalarFast(x, y, z) < -0.5f) {
					pData->SetScalar(x, y, z, 0.0f);
				}
			}
		}
	}
}

int main(int argc, char *argv[])
{
	if (ParseArguments(argc, argv) != 0) {
		PrintUsage();
		return 0;
	}

	pData = new CScalar();
	pData->OpenScalarFile(pSrcPathname);

	for (int ipass = 0; ipass < npass; ++ipass) {
		Dilate();
	}

	pData->SaveScalarFile(pDstPathname);

	SafeDelete(pData);

	return 0;
}